home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 March / CMCD0305.ISO / Software / Shareware / Utilitare / emu / Emu8086_Setup_307c.exe / {app} / Samples / ToBin.asm < prev    next >
Assembly Source File  |  2003-01-09  |  6KB  |  279 lines

  1. ; Copyright (C) 2002 - Alexander Popov 
  2. ; http://www.emu8086.com
  3.  
  4. ; This program inputs a decimal number
  5. ; and prints out its binary equivalent.
  6.  
  7. ; Convertion is done by CONVERT_TO_BIN
  8. ; procedure, all other stuff is just
  9. ; for input/output.
  10.  
  11.  
  12. ; for COM file:
  13. #make_COM#  
  14. ORG 100h
  15.  
  16. ; skipt data area:
  17. JMP start
  18.  
  19. ; The string to hold 8 bits
  20. ; of binary equivalent, reversed:
  21. Result db 8 dup('X')
  22.  
  23. start:
  24.  
  25. ; Print the message:
  26. CALL PTHIS
  27. db "Supported values from -127 to 255", 13, 10
  28. db "Enter the number: ", 0
  29.  
  30. ; Get the number:
  31. CALL SCAN_NUM
  32.  
  33. ; Go to new line:
  34. CALL PTHIS
  35. db 13, 10, 0
  36.  
  37. CALL CONVERT_TO_BIN
  38.  
  39. ; Print the message:
  40. CALL PTHIS
  41. db "Converted to binary:", 13, 10, 0
  42.  
  43. ; Print the Result string backwards:
  44. LEA SI, Result
  45. ADD SI, 7 ; point to end of the string.
  46. MOV AH, 0Eh ; teletype function of BIOS.
  47. MOV CX, 8
  48. print_me:
  49.     MOV AL, [SI]
  50.     INT 10h ; print in teletype mode.
  51.     DEC SI
  52. LOOP print_me
  53.  
  54. RET ; return to OS.
  55.  
  56. ; Procedure to convert number in CX
  57. ; to its binary equivalent. Result is
  58. ; store in "Result" string.
  59. CONVERT_TO_BIN PROC NEAR
  60.  
  61. PUSH AX
  62. PUSH DI
  63.  
  64. LEA DI, Result
  65.  
  66. MOV AX, CX
  67. MOV AH, 0   ; high byte ignored!
  68.  
  69. next_step:
  70.  
  71.     ; AL = AX / 2  
  72.     ; AH = remainder (can be 1 or 0)!
  73.     DIV CS:two
  74.     
  75.     MOV [DI], AH
  76.     ADD [DI], 30h ; convert to ASCII.
  77.     
  78.     INC DI
  79.     
  80.     ; we don't need remainder any more:
  81.     MOV AH, 0    
  82.     
  83. CMP AX, 0
  84. JNE next_step ; continue until result is zero.
  85.  
  86. ; Reset all prefix bits:
  87. do_reset:
  88.     CMP DI, OFFSET Result + 8
  89.     JAE done
  90.     MOV [DI], '0'
  91.     INC DI
  92.     JMP do_reset
  93. done:
  94.  
  95. POP DI
  96. POP AX
  97.  
  98. RET
  99.  
  100. two DB 2
  101.  
  102. CONVERT_TO_BIN ENDP
  103.  
  104. ; This macro prints a
  105. ; char in AL and advances
  106. ; the current cursor
  107. ; position:
  108. PUTC    MACRO   char
  109.         PUSH    AX
  110.         MOV     AL, char
  111.         MOV     AH, 0Eh
  112.         INT     10h     
  113.         POP     AX
  114. ENDM
  115.  
  116. ; This procedure gets the multi-digit
  117. ; SIGNED number from the keyboard,
  118. ; and stores the result in CX register:
  119. SCAN_NUM        PROC    NEAR
  120.         PUSH    DX
  121.         PUSH    AX
  122.         PUSH    SI
  123.         
  124.         MOV     CX, 0
  125.  
  126.         ; reset flag:
  127.         MOV     CS:make_minus, 0
  128.  
  129. next_digit:
  130.  
  131.         ; get char from keyboard
  132.         ; into AL:
  133.         MOV     AH, 00h
  134.         INT     16h
  135.         ; and print it:
  136.         MOV     AH, 0Eh
  137.         INT     10h
  138.  
  139.         ; check for MINUS:
  140.         CMP     AL, '-'
  141.         JE      set_minus
  142.  
  143.         ; check for ENTER key:
  144.         CMP     AL, 13  ; carriage return?
  145.         JNE     not_cr
  146.         JMP     stop_input
  147. not_cr:
  148.  
  149.  
  150.         CMP     AL, 8                   ; 'BACKSPACE' pressed?
  151.         JNE     backspace_checked
  152.         MOV     DX, 0                   ; remove last digit by
  153.         MOV     AX, CX                  ; division:
  154.         DIV     CS:ten                  ; AX = DX:AX / 10 (DX-rem).
  155.         MOV     CX, AX
  156.         PUTC    ' '                     ; clear position.
  157.         PUTC    8                       ; backspace again.
  158.         JMP     next_digit
  159. backspace_checked:
  160.  
  161.  
  162.         ; allow only digits:
  163.         CMP     AL, '0'
  164.         JAE     ok_AE_0
  165.         JMP     remove_not_digit
  166. ok_AE_0:        
  167.         CMP     AL, '9'
  168.         JBE     ok_digit
  169. remove_not_digit:       
  170.         PUTC    8       ; backspace.
  171.         PUTC    ' '     ; clear last entered not digit.
  172.         PUTC    8       ; backspace again.        
  173.         JMP     next_digit ; wait for next input.       
  174. ok_digit:
  175.  
  176.  
  177.         ; multiply CX by 10 (first time the result is zero)
  178.         PUSH    AX
  179.         MOV     AX, CX
  180.         MUL     CS:ten                  ; DX:AX = AX*10
  181.         MOV     CX, AX
  182.         POP     AX
  183.  
  184.         ; check if the number is too big
  185.         ; (result should be 16 bits)
  186.         CMP     DX, 0
  187.         JNE     too_big
  188.  
  189.         ; convert from ASCII code:
  190.         SUB     AL, 30h
  191.  
  192.         ; add AL to CX:
  193.         MOV     AH, 0
  194.         MOV     DX, CX      ; backup, in case the result will be too big.
  195.         ADD     CX, AX
  196.         JC      too_big2    ; jump if the number is too big.
  197.  
  198.         JMP     next_digit
  199.  
  200. set_minus:
  201.         MOV     CS:make_minus, 1
  202.         JMP     next_digit
  203.  
  204. too_big2:
  205.         MOV     CX, DX      ; restore the backuped value before add.
  206.         MOV     DX, 0       ; DX was zero before backup!
  207. too_big:
  208.         MOV     AX, CX
  209.         DIV     CS:ten  ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
  210.         MOV     CX, AX
  211.         PUTC    8       ; backspace.
  212.         PUTC    ' '     ; clear last entered digit.
  213.         PUTC    8       ; backspace again.        
  214.         JMP     next_digit ; wait for Enter/Backspace.
  215.         
  216.         
  217. stop_input:
  218.         ; check flag:
  219.         CMP     CS:make_minus, 0
  220.         JE      not_minus
  221.         NEG     CX
  222. not_minus:
  223.  
  224.         POP     SI
  225.         POP     AX
  226.         POP     DX
  227.         RET
  228. make_minus      DB      ?       ; used as a flag.
  229. ten             DW      10      ; used as multiplier.
  230. SCAN_NUM        ENDP
  231.  
  232.  
  233. ;***************************************************************
  234. ; This procedure prints a null terminated
  235. ; string at current cursor position.
  236. ; The ZERO TERMINATED string should be defined just after
  237. ; the CALL. For example:
  238. ;
  239. ; CALL PTHIS
  240. ; db 'Hello World!', 0
  241. ;
  242. ; Address of string is stored in the Stack as return address.
  243. ; Procedure updates value in the Stack to make return
  244. ; after string definition.
  245. PTHIS PROC NEAR
  246.  
  247. MOV     CS:temp1, SI  ; re-store SI register.
  248.  
  249. POP     SI            ; get return address (IP).
  250.  
  251. PUSH    AX            ; store AX register.
  252.  
  253. next_char:      
  254.         MOV     AL, CS:[SI]
  255.         INC     SI            ; next byte.
  256.         CMP     AL, 0
  257.         JZ      printed        
  258.         MOV     AH, 0Eh       ; teletype function.
  259.         INT     10h
  260.         JMP     next_char     ; loop.
  261. printed:
  262.  
  263. POP     AX            ; re-store AX register.
  264.  
  265. ; SI should point to next command after
  266. ; the CALL instruction and string definition:
  267. PUSH    SI            ; save new return address into the Stack.
  268.  
  269. MOV     SI, CS:temp1  ; re-store SI register.
  270.  
  271. RET
  272. temp1  DW  ?    ; variable to store original value of SI register.
  273. PTHIS ENDP
  274.  
  275.  
  276.  
  277. ; Copyright (C) 2002 - Alexander Popov 
  278. ; http://www.emu8086.com
  279.